﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TI_EntityLib.TiEntityObjects;
using System.Xml;
using TiPort.TiEntityObjects;
using System.Xml.Serialization;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.Serialization;
using TI_EntityLib.TiEntityObjects.DayLog;

namespace TiEntityObject.Transport
{
    public enum TransportFileStatusName { DownloadOk, UnzipOk, UnzipErr, ProcessedOk, ProcessedErr };
    public class TransportFileStatus {
        public TransportFileStatusName Status{ get; set; }
        public DateTime Date { get; set; }
        public string Message { get; set; }
    }

    /// <summary>
    /// Абстракция транспортного файла
    /// </summary>
    public class TransportFile
    {
        private string masterDataBatch = "masterDataBatch";     
        private XmlDocument document = null;
        private exportBase entityList = null;

        /// <summary>
        /// имя файла с расширением
        /// </summary>
        public string FileName { get; set; }

        /// <summary>
        /// имя файла без расширения
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// Статусы файла: Скачен как zip. Распакован в транспортный. Обработан - с результатом 
        /// </summary>
        public List<TransportFileStatus> StatusList { get; set; }

        public TransportFileStatus ImInstatus(TransportFileStatusName status)
        {
            foreach (TransportFileStatus i in this.StatusList)
            {
                if (i.Status == status)
                    return i;
            }
            return null;
        }
    
        public bool isProcessedOk
        {
            get
            {
                foreach (TransportFileStatus i in this.StatusList)
                {
                    if (i.Status == TransportFileStatusName.ProcessedOk )
                        return true;
                }
                return false;
            }
        }

        public DateTime Date {
            get
            {
                string value=Regex.Match(Name ,@"[0-9]{8}").Value;
                string y = value.Substring(0, 4);
                string m = value.Substring(4, 2);
                string d = value.Substring(6, 2);

                return Convert.ToDateTime (d+"."+m+"."+y) ;
            }
        }

        public TransportFile() { }
        
        public TransportFile(string workFolder, string fileName)
        {
            this.FileName = fileName;
            this.WorckFolder = workFolder;
            FileInfo inf = new FileInfo(fileName);
            this.Name = inf.Name.Replace(inf.Extension, string.Empty);   
            this.StatusList =new List<TransportFileStatus> () ;
            this.StatusList.Add (new TransportFileStatus (){Date =DateTime.Now,Status = TransportFileStatusName.DownloadOk});   
        }

        public TransportFile(string fileName )
        {
            this.FileName = fileName;
            FileInfo fi = new FileInfo(fileName);
            this.WorckFolder = fi.DirectoryName;
        }

        public FtpTiTypeFiles FileType { get {
            if (FileName.ToUpper().IndexOf("_ALL") > -1)
                return FtpTiTypeFiles.All;
            return FtpTiTypeFiles.Inc;
        } 
        }

        /// <summary>
        /// Статус загрузки 
        /// </summary>
        public string isStatusLoded{ get; set; }
    
        public string WorckFolder { get; set; }

        public TiContetFileType ContentType
        {
            get
            {
                if (FileName.ToUpper().IndexOf("NOTIFI") > -1)
                    return TiContetFileType.Notification;

                if (FileName.ToUpper().IndexOf("CONTRACT") > -1)
                    return TiContetFileType.Contract;

                if (FileName.ToUpper().IndexOf("PROTOCOL") > -1)
                    return TiContetFileType.Protocol ;
                
                return TiContetFileType.None;
            }
        }

        public int EntityCount { get; set; }

        /// <summary>
        /// Воможные исключения файл не найден
        /// Файл не загружается (битый и т.п.)
        /// </summary>
        public void Load()
        {
            XmlDocument d = new XmlDocument();
            d.Load(WorckFolder+@"\" + Name+".xml" );
            document = Helper.XmlTools.GetXmlNoNamespaceDocument(d);
        }

        /// <summary>
        /// Вернуть коллекцию бизнес объектов представленных в файле. дата транспортировки (попадания в систему ставиться=transportDay )
        /// </summary>
        /// <param name="transportDay"></param>
        /// <returns></returns>
        public exportBase GetEntityList(DateTime transportDay)
        {
            if (entityList != null)
                          return entityList;

            if(document ==null)
                return null;

            try
            {
                // определяем тип транспорта
                if (this.document.ChildNodes[1].Name == masterDataBatch)
                {
                    XmlSerializer mySerializer = new XmlSerializer(typeof(masterDataBatch));
                    XmlNodeReader r = new XmlNodeReader(this.document.ChildNodes[1]);
                    this.entityList = (masterDataBatch)mySerializer.Deserialize(r);                   
                }
                else
                {
                    XmlSerializer mySerializer = new XmlSerializer(typeof(export));
                    XmlNodeReader r = new XmlNodeReader(this.document.ChildNodes[1]);
                    this.entityList = (export)mySerializer.Deserialize(r);
                  
                }

                foreach (IDbRootObject i in entityList.GetCollection())
                {
                    i.FileName = this.Name ;
                    i.iFileDate = Helper.Time.GetDateInMS(this.Date);
                    i.iTransportDay = Helper.Time.GetDateInMS(transportDay);
                }
                return entityList;
            }     
            catch
            {
                return null;
            }


        }
      
        /// <summary>
        /// Сначала идут All
        /// заявки
        /// контракты   
        /// протоколы
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public static int Comparer(TransportFile x, TransportFile y)
        {
            string iX =string.Empty , iY=string.Empty ;

            iX =iX+AddComparePref(x, ref iX);
            iY =iY+ AddComparePref(y, ref iY);

            iX = iX+(x.FileType == FtpTiTypeFiles.All ? "1" : "2");
            iY = iY+(y.FileType == FtpTiTypeFiles.All ? "1" : "2");

            iX =iX +"_"+x.Date.ToBinary().ToString();
            iY = iY + "_" + y.Date.ToBinary().ToString();     

            return iX.CompareTo(iY);               

        }

        public void AddStatusList(TransportFileStatus status) {

            foreach (TransportFileStatus i in this.StatusList)
            {
                if (i.Status == status.Status)
                {
                    i.Date = status.Date;
                    return;
                }
            }
            this.StatusList.Add(status);
        }

        private static string AddComparePref(TransportFile x, ref string pref)
        {
            if(x.ContentType == TiContetFileType.Notification) pref=pref+"A";
            if (x.ContentType == TiContetFileType.Contract ) pref = pref + "B";
            if (x.ContentType == TiContetFileType.Protocol ) pref = pref + "C";
            return pref;
        }

        public override string ToString()
        {
            string s = Helper.Json<TransportFile>.NewtonSerializeObject(this);
            return s;
        }
    }
}
